
//-----------------MATRICES---------------
float4x4 xWorld: World;				
float4x4 xView: View;
float4x4 xProjection: Projection;
float4x4 xRotationMatrix;



//-----------------TEXTURES---------------

Texture xTexture;
sampler ColoredTextureSampler = sampler_state { texture = <xTexture> ;
    magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = mirror; AddressV = mirror;};

Texture xDirtTexture;
sampler DirtTextureSampler = sampler_state { texture = <xDirtTexture> ;
    magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = mirror; AddressV = mirror;};

Texture xGrassTexture;
sampler GrassTextureSampler = sampler_state { texture = <xGrassTexture> ;
    magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = mirror; AddressV = mirror;};

Texture xRockTexture;
sampler RockTextureSampler = sampler_state { texture = <xRockTexture> ;
    magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = mirror; AddressV = mirror;};

Texture xSnowTexture;
sampler SnowTextureSampler = sampler_state { texture = <xSnowTexture> ;
    magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = mirror; AddressV = mirror;};


//--------------- CONSTANTS ---------------

float xMaxHeight;
float xMinHeight;

bool xRefraction;




float4 xLightPosition;
float4 xAmbientLight;
float4 xCameraPosition;


float xWaterLevel;



//------------------- STRUCTS -------------------   


struct BufferToVertex
{
float3 Pos : POSITION;
float4 Normal : NORMAL;
float4 UV : TEXCOORD0;

};


struct VertexToPixel
{
float4 Pos:POSITION;
float4 Orig_Pos:TEXCOORD1;
float4 UV:TEXCOORD0;
float4 Normal: TEXCOORD2;
float4 TexWeights: TEXCOORD3;
float4 Pos3D:TEXCOORD4;
float4 Pos2D:TEXCOORD5;
};


struct PixelToFrame
{
float4 Color:COLOR;
float Depth:DEPTH;
};






//---------------------- SHADERS ------------------------


// ---- MULTITEXTURED --------

VertexToPixel multitexturedVS(BufferToVertex IN)
{
  VertexToPixel OUT = (VertexToPixel)0;
  float4x4 WorldViewProj;
  WorldViewProj=mul(xWorld,xView);
  WorldViewProj=mul(WorldViewProj,xProjection);
  OUT.Pos=mul(float4(IN.Pos.xyz,1.0), WorldViewProj);
  OUT.Pos2D=OUT.Pos;
  OUT.Orig_Pos=float4(IN.Pos.xyz,1.0);
  OUT.Pos3D=mul(float4(IN.Pos.xyz,1.0),xWorld);
  OUT.UV=float4(IN.UV.xy,1.0,1.0);
  OUT.Normal=IN.Normal;
  float t=(IN.Pos.z-xMinHeight)/(xMaxHeight-xMinHeight);
  if (t<(1.0/7.0)) OUT.TexWeights=float4(1.0,0.0,0.0,0.0);
  if ((t>=(1.0/7.0)) && ((t<2.0/7.0))) OUT.TexWeights=float4(2.0-7.0*t,7.0*t-1,0.0,0.0);
  if ((t>=(2.0/7.0)) && ((t<3.0/7.0))) OUT.TexWeights=float4(0.0,1.0,0.0,0.0);
  if ((t>=(3.0/7.0)) && ((t<4.0/7.0))) OUT.TexWeights=float4(0.0,4.0-7.0*t,7.0*t-3,0.0);
  if ((t>=(4.0/7.0)) && ((t<5.0/7.0))) OUT.TexWeights=float4(0.0,0.0,1.0,0.0);
  if ((t>=(5.0/7.0)) && ((t<6.0/7.0))) OUT.TexWeights=float4(0.0,0.0,6.0-7.0*t,7.0*t-5.0);
  if (t>=(6.0/7.0)) OUT.TexWeights=float4(0.0,0.0,0.0,1.0);
  return OUT;
}


PixelToFrame multitexturedPS(VertexToPixel IN) 
{
PixelToFrame OUT=(PixelToFrame)0;
OUT.Depth=IN.Pos2D.z/IN.Pos2D.w;
float4 LightVector = normalize(xLightPosition-IN.Orig_Pos);

float LightIntensity = dot(LightVector, normalize(mul(IN.Normal,xRotationMatrix)));

if (xRefraction) if (IN.Pos3D.z>xWaterLevel) {OUT.Depth=1.0;LightIntensity=0.0f; xAmbientLight=float4(0,0,0,0);} 	

OUT.Color = saturate((tex2D(DirtTextureSampler, IN.UV)*IN.TexWeights.x+
       		      tex2D(GrassTextureSampler, IN.UV)*IN.TexWeights.y+
                      tex2D(RockTextureSampler, IN.UV)*IN.TexWeights.z+
                      tex2D(SnowTextureSampler, IN.UV)*IN.TexWeights.w)*LightIntensity+xAmbientLight);
return OUT;       
}

//---------- TEXTURED ---------------

VertexToPixel texturedVS(BufferToVertex IN)
{
  VertexToPixel OUT = (VertexToPixel)0;
  float4x4 WorldViewProj;
  WorldViewProj=mul(xWorld,xView);
  WorldViewProj=mul(WorldViewProj,xProjection);
  OUT.Pos=mul(float4(IN.Pos.xyz,1.0), WorldViewProj);
  OUT.Pos2D=OUT.Pos;
  OUT.Pos3D=mul(float4(IN.Pos.xyz,1.0),xWorld);
  OUT.Orig_Pos=float4(IN.Pos.xyz,1.0);
  OUT.UV=float4(IN.UV.xy,1.0,1.0);
  OUT.Normal=IN.Normal;
	return OUT;
}

PixelToFrame texturedPS(VertexToPixel IN) 
{
PixelToFrame OUT = (PixelToFrame)0;
OUT.Depth=IN.Pos2D.z/IN.Pos2D.w;
float4 LightVector = normalize(xLightPosition - IN.Orig_Pos);
float LightIntensity = dot(LightVector,normalize(mul(IN.Normal,xRotationMatrix)));

if (xRefraction) if (IN.Pos3D.z>xWaterLevel) {OUT.Depth=1.0; LightIntensity=0.0f; xAmbientLight=float4(0,0,0,0);} 	
	
OUT.Color = saturate(tex2D(ColoredTextureSampler, IN.UV)*LightIntensity+xAmbientLight);
return OUT;
}





//----------- TEXTURED (NO LIGHTING) ----------
VertexToPixel nolighttexturedVS(BufferToVertex IN)
{
  VertexToPixel OUT = (VertexToPixel)0;
  float4x4 WorldViewProj;
  WorldViewProj=mul(xWorld,xView);
  WorldViewProj=mul(WorldViewProj,xProjection);
  OUT.Pos=mul(float4(IN.Pos.xyz,1.0), WorldViewProj);
  OUT.Pos2D=OUT.Pos;
  OUT.Pos3D=mul(float4(IN.Pos.xyz,1.0),xWorld);
  OUT.Orig_Pos=float4(IN.Pos.xyz,1.0);
  OUT.UV=float4(IN.UV.xy,1.0,1.0);
  OUT.Normal=IN.Normal;
  return OUT;
}

PixelToFrame nolighttexturedPS(VertexToPixel IN) 
{
PixelToFrame OUT = (PixelToFrame)0;
OUT.Depth=IN.Pos2D.z/IN.Pos2D.w;
OUT.Color = saturate(tex2D(ColoredTextureSampler, IN.UV)+xAmbientLight);

if (xRefraction) if (IN.Pos3D.z>xWaterLevel) {OUT.Depth=1.0; OUT.Color=float4(0,0,0,0);} 	

return OUT;
}





// ------------ TECHNIQUES --------------

technique nolighttextured {
	pass p0 {
		VertexShader = compile vs_3_0 nolighttexturedVS();
		PixelShader = compile ps_3_0 nolighttexturedPS();
	}
}

technique textured {
	pass p0 {
		VertexShader = compile vs_3_0 texturedVS();
		PixelShader = compile ps_3_0 texturedPS();
	}
}


technique multitextured {
	pass p0 {
		VertexShader = compile vs_3_0 multitexturedVS();
		PixelShader = compile ps_3_0 multitexturedPS();
	}
}

